package com.ashley.phonemsn

import android.Manifest
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.telecom.TelecomManager
import android.view.KeyEvent
import android.telephony.PhoneStateListener
import android.telephony.TelephonyManager
import android.util.Log
import android.widget.Toast
import androidx.compose.runtime.mutableStateOf
import androidx.core.content.ContextCompat
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.util.concurrent.atomic.AtomicBoolean

class CallViewModel : ViewModel() {
    private val TAG = "CallViewModel"

    // 电话号码输入框内容
    val phoneNumber = mutableStateOf("")
    
    // 联系人名称
    val contactName = mutableStateOf("")
    
    // 存储电话号码到联系人名称的映射
    private val contactNames = mutableMapOf("10086" to "中国移动客服")

    // 通话状态
    val isInCall = mutableStateOf(false)
    var callStartTime: Long = 0
        private set
    val callDuration = mutableStateOf("00:00")
    private var timerHandler: Handler? = null
    private val isTimerRunning = AtomicBoolean(false)

    // 电话状态监听
    private var telephonyManager: TelephonyManager? = null
    private var phoneStateListener: PhoneStateListener? = null

    // TelecomManager实例
    private var telecomManager: TelecomManager? = null

    // 来电相关状态
    val incomingCallNumber = mutableStateOf("")
    val isIncomingCall = mutableStateOf(false)

    // 初始化服务
    fun initServices(context: Context) {
        try {
            telecomManager = context.getSystemService(Context.TELECOM_SERVICE) as? TelecomManager
            
            // 启动拨号拦截服务
            CallInterceptService.startService(context)
            
            Log.d(TAG, "TelecomManager 初始化成功，拨号拦截服务已启动")
        } catch (e: Exception) {
            Log.e(TAG, "初始化TelecomManager失败", e)
        }
    }

    // 检查电话状态权限
    fun checkPhoneStatePermission(context: Context): Boolean {
        return ContextCompat.checkSelfPermission(
            context,
            Manifest.permission.READ_PHONE_STATE
        ) == android.content.pm.PackageManager.PERMISSION_GRANTED
    }

    // 设置电话状态监听
    fun setupPhoneStateListener(context: Context) {
        try {
            telephonyManager = context.getSystemService(Context.TELEPHONY_SERVICE) as? TelephonyManager
            if (telephonyManager == null) {
                Log.e(TAG, "无法获取TelephonyManager服务")
                return
            }

            phoneStateListener = object : PhoneStateListener() {
                override fun onCallStateChanged(state: Int, incomingNumber: String?) {
                    try {
                        when (state) {
                            TelephonyManager.CALL_STATE_RINGING -> {
                                // 来电
                                Log.d(TAG, "来电: $incomingNumber")
                                incomingCallNumber.value = incomingNumber ?: "未知号码"
                                isIncomingCall.value = true
                                
                                // 自动启动接听服务
                                startCallAnswerService(context, incomingNumber)
                            }
                            TelephonyManager.CALL_STATE_OFFHOOK -> {
                                // 通话开始
                                Log.d(TAG, "通话开始")
                                isIncomingCall.value = false
                                if (!isInCall.value) {
                                    startCall()
                                }
                            }
                            TelephonyManager.CALL_STATE_IDLE -> {
                                // 通话结束
                                Log.d(TAG, "通话结束")
                                isIncomingCall.value = false
                                if (isInCall.value) {
                                    endCall(context)
                                }
                            }
                        }
                    } catch (e: Exception) {
                        Log.e(TAG, "处理电话状态变化时出错", e)
                    }
                }
            }

            // 安全地设置监听
            telephonyManager?.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE)
            Log.d(TAG, "电话状态监听已设置")
        } catch (e: SecurityException) {
            Log.e(TAG, "设置电话状态监听时权限不足", e)
            showToast(context, "电话状态监听权限不足")
        } catch (e: Exception) {
            Log.e(TAG, "设置电话状态监听失败", e)
        }
    }

    // 移除电话状态监听
    fun removePhoneStateListener() {
        try {
            if (phoneStateListener != null && telephonyManager != null) {
                telephonyManager?.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE)
                Log.d(TAG, "电话状态监听已移除")
            }
            phoneStateListener = null
            telephonyManager = null
        } catch (e: Exception) {
            Log.e(TAG, "移除电话状态监听时出错", e)
        }
    }

    // 更新电话号码
    fun updatePhoneNumber(number: String, contactName: String? = null) {
        // 立即更新电话号码
        phoneNumber.value = number
        
        // 创建一个新的mutableMap来更新联系人名称映射，确保UI能够检测到变化
        val updatedContactNames = contactNames.toMutableMap()
        if (contactName != null) {
            updatedContactNames[number] = contactName
            // 替换整个map对象而不是修改其内容
            contactNames.clear()
            contactNames.putAll(updatedContactNames)
            // 更新当前联系人名称
            this.contactName.value = contactName
        } else {
            // 如果没有提供联系人名称，尝试从已有映射中获取
            this.contactName.value = contactNames.getOrDefault(number, number)
        }
    }

    // 使用应用内拨打电话（不通过系统应用）
    fun makePhoneCall(context: Context) {
        if (phoneNumber.value.isEmpty()) {
            showToast(context, "请输入电话号码")
            return
        }

        try {
            // 直接使用TelecomManager进行应用内拨号
            if (telecomManager != null) {
                val uri = Uri.fromParts("tel", phoneNumber.value, null)
                val extras = android.os.Bundle().apply {
                    putBoolean(TelecomManager.EXTRA_START_CALL_WITH_SPEAKERPHONE, false)
                    // 添加标志，表明这是应用内拨号
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                        putBoolean(TelecomManager.EXTRA_CALL_SUBJECT, true)
                    }
                }

                // 直接拨号，不显示系统拨号界面
                telecomManager!!.placeCall(uri, extras)
                Log.d(TAG, "应用内拨打电话: $phoneNumber")

                // 立即开始通话状态
                startCall()
                showToast(context, "正在呼叫 $phoneNumber")
                return
            }

            // 备选方式：使用自定义拨号逻辑
            Log.w(TAG, "TelecomManager不可用，使用自定义拨号逻辑")
            makePhoneCallDirectly(context)

        } catch (e: SecurityException) {
            Log.e(TAG, "拨打电话权限不足", e)
            showToast(context, "拨打电话权限不足")
        } catch (e: Exception) {
            Log.e(TAG, "拨打电话失败", e)
            showToast(context, "拨打电话失败: ${e.message}")
        }
    }

    // 自定义直接拨号逻辑
    private fun makePhoneCallDirectly(context: Context) {
        try {
            // 模拟拨号过程
            Log.d(TAG, "开始自定义拨号: $phoneNumber")
            
            // 立即开始通话状态
            startCall()
            showToast(context, "正在呼叫 $phoneNumber")
            
            // 这里可以添加更多自定义拨号逻辑
            // 例如：使用反射调用隐藏的TelephonyManager方法
            
        } catch (e: Exception) {
            Log.e(TAG, "自定义拨号失败", e)
            showToast(context, "拨号失败，请检查权限设置")
        }
    }

    // 开始通话
    fun startCall() {
        isInCall.value = true
        callStartTime = System.currentTimeMillis()
        startCallTimer()
        Log.d(TAG, "通话开始")
    }

    // 开始通话计时器
    private fun startCallTimer() {
        // 避免重复启动计时器
        if (isTimerRunning.getAndSet(true)) {
            return
        }

        timerHandler = Handler(Looper.getMainLooper())
        timerHandler?.postDelayed(object : Runnable {
            override fun run() {
                if (isInCall.value) {
                    val durationMillis = System.currentTimeMillis() - callStartTime
                    val seconds = (durationMillis / 1000).toInt()
                    val minutes = seconds / 60
                    val remainingSeconds = seconds % 60
                    callDuration.value = String.format("%02d:%02d", minutes, remainingSeconds)
                    timerHandler?.postDelayed(this, 1000)
                } else {
                    isTimerRunning.set(false)
                }
            }
        }, 1000)
    }

    // 停止计时器
    private fun stopCallTimer() {
        if (timerHandler != null) {
            timerHandler?.removeCallbacksAndMessages(null)
            timerHandler = null
        }
        isTimerRunning.set(false)
        callDuration.value = "00:00"
    }

    // 使用TelecomManager结束通话
    fun endCall(context: Context) {
        try {
            // 设置通话状态为结束
            isInCall.value = false

            // 停止计时器
            stopCallTimer()

            // 首选方式：使用TelecomManager结束通话
            if (telecomManager != null) {
                try {
                    // 使用反射调用endCall方法，因为endCall()方法在API级别28及以上才可用
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                        val method = telecomManager!!::class.java.getMethod("endCall")
                        val success = method.invoke(telecomManager!!) as Boolean
                        Log.d(TAG, "使用TelecomManager结束通话: $success")
                    } else {
                        // 对于Android P以下版本，使用备选方式
                        endCallFallback(context)
                    }
                } catch (e: SecurityException) {
                    Log.w(TAG, "TelecomManager结束通话权限不足，使用备选方式", e)
                    endCallFallback(context)
                } catch (e: Exception) {
                    Log.w(TAG, "TelecomManager结束通话失败，使用备选方式", e)
                    endCallFallback(context)
                }
            } else {
                // TelecomManager不可用，使用备选方式
                endCallFallback(context)
            }

            Log.d(TAG, "通话结束")
            showToast(context, "通话结束")

        } catch (e: Exception) {
            Log.e(TAG, "处理结束通话时出错", e)
            // 确保状态被重置
            isInCall.value = false
            stopCallTimer()
        }
    }

    // 结束通话的备选方式
    private fun endCallFallback(context: Context) {
        try {
            // 备选方式：使用Intent结束通话
            val intent = Intent(Intent.ACTION_MEDIA_BUTTON).apply {
                putExtra(Intent.EXTRA_KEY_EVENT, KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENDCALL))
            }
            context.sendOrderedBroadcast(intent, null)
            Log.d(TAG, "使用备选方式结束通话")
        } catch (e: Exception) {
            Log.e(TAG, "备选结束通话方式也失败", e)
        }
    }

    // 切换扬声器
    fun toggleSpeaker(context: Context) {
        // 这里可以实现扬声器切换逻辑
        showToast(context, "切换扬声器")
    }

    // 显示拨号盘
    fun showDialpad(context: Context) {
        // 这里可以在通话中显示拨号盘
        showToast(context, "显示拨号盘")
    }

    // 安全显示Toast
    private fun showToast(context: Context, message: String) {
        viewModelScope.launch(Dispatchers.Main) {
            try {
                Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
            } catch (e: Exception) {
                Log.w(TAG, "显示Toast失败", e)
            }
        }
    }

    // 清理资源
    fun cleanup() {
        try {
            // 确保清理资源
            isInCall.value = false

            // 安全地清理计时器
            stopCallTimer()

            // 移除监听
            removePhoneStateListener()

            // 清理TelecomManager引用
            telecomManager = null

            Log.d(TAG, "CallViewModel资源已完全清理")
        } catch (e: Exception) {
            Log.e(TAG, "清理资源出错", e)
        } finally {
            // 确保关键变量被重置，即使发生异常
            phoneStateListener = null
            telephonyManager = null
            telecomManager = null
        }
    }

    override fun onCleared() {
        super.onCleared()
        cleanup()
    }

    // 接听电话相关方法
    
    /**
     * 启动电话接听服务
     */
    private fun startCallAnswerService(context: Context, phoneNumber: String?) {
        try {
            CallAnswerService.startService(context, phoneNumber)
            Log.d(TAG, "电话接听服务已启动")
        } catch (e: Exception) {
            Log.e(TAG, "启动电话接听服务失败", e)
        }
    }
    
    /**
     * 停止电话接听服务
     */
    fun stopCallAnswerService(context: Context) {
        try {
            CallAnswerService.stopService(context)
            Log.d(TAG, "电话接听服务已停止")
        } catch (e: Exception) {
            Log.e(TAG, "停止电话接听服务失败", e)
        }
    }
    
    /**
     * 接听来电
     */
    fun answerIncomingCall(context: Context) {
        try {
            // 使用Intent启动接听服务
            val intent = Intent(context, CallAnswerService::class.java).apply {
                action = CallAnswerService.ACTION_ANSWER_CALL
                putExtra(CallAnswerService.EXTRA_PHONE_NUMBER, incomingCallNumber.value)
            }
            
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                context.startForegroundService(intent)
            } else {
                context.startService(intent)
            }
            
            Log.d(TAG, "正在接听来电: ${incomingCallNumber.value}")
            showToast(context, "正在接听来电")
            
        } catch (e: SecurityException) {
            Log.e(TAG, "接听电话权限不足", e)
            showToast(context, "接听电话权限不足")
        } catch (e: Exception) {
            Log.e(TAG, "接听电话失败", e)
            showToast(context, "接听电话失败")
        }
    }
    
    /**
     * 拒绝来电
     */
    fun rejectIncomingCall(context: Context) {
        try {
            // 使用Intent启动拒绝服务
            val intent = Intent(context, CallAnswerService::class.java).apply {
                action = CallAnswerService.ACTION_REJECT_CALL
                putExtra(CallAnswerService.EXTRA_PHONE_NUMBER, incomingCallNumber.value)
            }
            
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                context.startForegroundService(intent)
            } else {
                context.startService(intent)
            }
            
            // 重置来电状态
            isIncomingCall.value = false
            incomingCallNumber.value = ""
            
            Log.d(TAG, "已拒绝来电: ${incomingCallNumber.value}")
            showToast(context, "已拒绝来电")
            
        } catch (e: SecurityException) {
            Log.e(TAG, "拒绝电话权限不足", e)
            showToast(context, "拒绝电话权限不足")
        } catch (e: Exception) {
            Log.e(TAG, "拒绝电话失败", e)
            showToast(context, "拒绝电话失败")
        }
    }
}